package com.topcent.tioxyc.util;


import cn.hutool.http.HttpRequest;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.topcent.tioxyc.constants.KeyConstant;
import com.topcent.tioxyc.pojo.Assignee;
import com.topcent.tioxyc.pojo.JdyPurchaseOrder;
import com.topcent.tioxyc.pojo.vo.Lin;
import com.topcent.tioxyc.util.exception.BizException;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.Header;
import org.apache.http.message.BasicHeader;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.math.BigDecimal;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author: 向伟典
 * @date: 2023/8/31 15:51
 * @Description: 工具类
 */
@Slf4j
public class ConnmeUtils {

    public static <T> T mapToObject(Map<String, Object> map, Class<T> clazz) {
        String jsonStr = JSONUtil.toJsonStr(map);
        ObjectMapper objectMapper = new ObjectMapper();
        try {
            return objectMapper.readValue(jsonStr, clazz);
        } catch (JsonProcessingException e) {
            throw new BizException("在转换BizContent集合是出现了错误，对象为" + clazz);
        }
    }

    public static Header[] createHeaders() {
        Header[] headers = new Header[2];
        headers[0] = new BasicHeader("Authorization", "Bearer " + KeyConstant.JDY_KEY);
        headers[1] = new BasicHeader("Content-Type", "application/json;charset=utf-8");
        return headers;
    }

    public static String liuChen(String id) {
        Header[] headers = ConnmeUtils.createHeaders();
        Map<String, Object> parameterDelete = new HashMap<>();
        parameterDelete.put("instance_id", id);
        parameterDelete.put("tasks_type", 1);
        String jsonSale = JSONUtil.toJsonStr(parameterDelete);
        JSONObject jdySale = ApiClient.sendPostRequest(KeyConstant.Jian_URL + "/v5/workflow/instance/get", headers, jsonSale);
        JdyPurchaseOrder jdyPurchaseOrder = JSONUtil.toBean(jdySale, JdyPurchaseOrder.class);
        int size = jdyPurchaseOrder.getTasks().size() - 1;
        Assignee assignee = jdyPurchaseOrder.getTasks().get(size).getAssignee();
        return assignee.getName();

    }

    /**
     * 根据对象，获取简道云传输格式
     */
    public static Map<String, Object> convertEntityToMap(Object entity) {
        Map<String, Object> data = new HashMap<>();
        Class<?> clazz = entity.getClass();

        try {
            Field[] fields = clazz.getDeclaredFields();
            for (Field field : fields) {
                field.setAccessible(true);
                Object value = field.get(entity);

                // 将字段名转换为小写
                String fieldName = field.getName().toLowerCase();

                // 如果字段值是列表类型（List 或其他集合类型），递归处理每个列表项
                if (value instanceof List<?>) {
                    List<Object> listValue = (List<Object>) value;
                    Map<String, Object> mapData = new HashMap<>();

                    // 判断是否为 String 列表（非空时检查第一个元素类型）
                    boolean isStringList = listValue.isEmpty()
                            ? false
                            : listValue.getFirst() instanceof String;

                    if (isStringList) {
                        // 处理 List<String>：直接将列表作为 "value" 的值
                        mapData.put("value", listValue);
                    } else {
                        // 处理其他类型列表（如 List<对象>）：递归转换每个元素
                        List<Map<String, Object>> listData = new ArrayList<>();
                        for (Object listItem : listValue) {
                            listData.add(convertEntityToMapNull(listItem));
                        }
                        mapData.put("value", listData);
                    }
                    data.put(fieldName, mapData);
                    // 如果字段值是列表类型，将列表作为一个值添加到 data 中
                    /*List<Map<String, Object>> listData = new ArrayList<>();
                    for (Object listItem : (List<?>) value) {
                        listData.add(convertEntityToMap(listItem));
                    }
                    Map<String, Object> mapData = new HashMap<>();
                    mapData.put("value", listData);
                    data.put(fieldName, mapData);*/
                } else if (value instanceof Map<?, ?>) {
                    // 如果字段值是 Map 类型，递归处理每个子项
                    Map<String, Object> mapData = new HashMap<>();
                    for (Map.Entry<?, ?> entry : ((Map<?, ?>) value).entrySet()) {
                        Object mapKey = entry.getKey();
                        Object mapValue = entry.getValue();
                        if (mapValue instanceof List<?>) {
                            List<Map<String, Object>> listData = new ArrayList<>();
                            for (Object listItem : (List<?>) mapValue) {
                                Map<String, Object> listItemMap = new HashMap<>();
                                listItemMap.put("value", listItem != null ? listItem : "");
                                listData.add(listItemMap);
                            }
                            mapData.put(mapKey.toString(), listData);
                        } else {
                            mapData.put(mapKey.toString(), mapValue != null ? mapValue : "");
                        }
                    }
                    data.put(fieldName, mapData);
                } else {
                    // 否则，将字段值作为单个属性添加到 data 中
                    Map<String, Object> pa = new HashMap<String, Object>();
                    pa.put("value", value);
                    data.put(fieldName, pa);
                }
            }
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }

        return data;
    }

    /**
     * 比较两个对象是否相等
     */
    public static boolean deepEquals(Object obj1, Object obj2) {
        // 检查是否为null
        if (obj1 == null || obj2 == null) {
            return false;
        }

        // 检查对象是否为同一类型
        if (!obj1.getClass().equals(obj2.getClass())) {
            return false;
        }

        // 获取对象的所有字段
        Field[] fields = obj1.getClass().getDeclaredFields();

        try {
            for (Field field : fields) {
                field.setAccessible(true);

                // 获取字段的值
                Object value1 = field.get(obj1);
                Object value2 = field.get(obj2);

                // 递归比较集合对象
                if (value1 instanceof Collection && value2 instanceof Collection) {
                    if (!deepCollectionEquals((Collection<?>) value1, (Collection<?>) value2)) {
                        return false;
                    }
                } else if (!Objects.equals(value1, value2)) {
                    return false;
                }
            }
        } catch (IllegalAccessException e) {
            e.printStackTrace();
            return false;
        }

        return true;
    }

    private static boolean deepCollectionEquals(Collection<?> collection1, Collection<?> collection2) {
        if (collection1.size() != collection2.size()) {
            return false;
        }

        // 检查集合中的元素是否相等
        for (Object element1 : collection1) {
            boolean found = false;
            for (Object element2 : collection2) {
                if (deepEquals(element1, element2)) {
                    found = true;
                    break;
                }
            }
            if (!found) {
                return false;
            }
        }

        return true;
    }


    public static String gettoken() {
        HttpRequest post = HttpRequest.get(" https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid=wwfe95ca727f125b88&corpsecret=6VX1EQzZKm_Sj2Jqqev75a7gOEhBM-33G4vsCoSL21c");
        String body = post.execute().body();
        JSONObject entries = JSONUtil.parseObj(body);
        return entries.getStr("access_token");
    }

    public static String getJandaoyyunToken() {
        HttpRequest post = HttpRequest.get(" https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid=wwfe95ca727f125b88&corpsecret=DFX-kGgtV7oMM3CixBjzfHHxKjS2RcjoJrDfwWMIFwg");
        String body = post.execute().body();
        JSONObject entries = JSONUtil.parseObj(body);
        return entries.getStr("access_token");
    }

    public static Map<String, Object> convertEntityToMapNull(Object entity) {
        Map<String, Object> data = new HashMap<>();
        if(entity == null){
            return data;
        }
        Class<?> clazz = entity.getClass();

        try {
            Field[] fields = clazz.getDeclaredFields();
            for (Field field : fields) {
                field.setAccessible(true);
                Object value = field.get(entity);

                // 将字段名转换为小写
                String fieldName = field.getName().toLowerCase();

                // 跳过 null 值的字段
                if (value == null) {
                    continue;
                }

                // 如果字段值是列表类型（List 或其他集合类型），递归处理每个列表项
                if (value instanceof List<?>) {
                    List<Object> listValue = (List<Object>) value;
                    Map<String, Object> mapData = new HashMap<>();

                    // 判断是否为 String 列表（非空时检查第一个元素类型）
                    boolean isStringList = listValue.isEmpty()
                            ? false
                            : listValue.getFirst() instanceof String;

                    if (isStringList) {
                        // 处理 List<String>：直接将列表作为 "value" 的值
                        mapData.put("value", listValue);
                    } else {
                        // 处理其他类型列表（如 List<对象>）：递归转换每个元素
                        List<Map<String, Object>> listData = new ArrayList<>();
                        for (Object listItem : listValue) {
                            listData.add(convertEntityToMapNull(listItem));
                        }
                        mapData.put("value", listData);
                    }
                    data.put(fieldName, mapData);
                    /*log.info("日志排查6List===》{}",value);
                    // 如果字段值是列表类型，将列表作为一个值添加到 data 中
                    List<Map<String, Object>> listData = new ArrayList<>();
                    for (Object listItem : (List<?>) value) {
                        listData.add(convertEntityToMapNull(listItem));
                    }
                    Map<String, Object> mapData = new HashMap<>();
                    mapData.put("value", listData);
                    data.put(fieldName, mapData);*/
                } else if (value instanceof Map<?, ?>) {
                    // 如果字段值是 Map 类型，递归处理每个子项
                    Map<String, Object> mapData = new HashMap<>();
                    for (Map.Entry<?, ?> entry : ((Map<?, ?>) value).entrySet()) {
                        Object mapKey = entry.getKey();
                        Object mapValue = entry.getValue();
                        if (mapValue instanceof List<?>) {
                            List<Map<String, Object>> listData = new ArrayList<>();
                            for (Object listItem : (List<?>) mapValue) {
                                Map<String, Object> listItemMap = new HashMap<>();
                                listItemMap.put("value", listItem != null ? listItem : "");
                                listData.add(listItemMap);
                            }
                            mapData.put(mapKey.toString(), listData);
                        } else {
                            mapData.put(mapKey.toString(), mapValue != null ? mapValue : "");
                        }
                    }
                    data.put(fieldName, mapData);
                } else {
                    // 否则，将字段值作为单个属性添加到 data 中
                    Map<String, Object> pa = new HashMap<>();
                    pa.put("value", value);
                    data.put(fieldName, pa);
                }
            }
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
        return data;
    }

    /**
     * 使用正则表达式提取括号中的数字部分
     *
     * @param dateString
     * @return
     */
    public static String extractTimestamp(String dateString) {
        // 提取时间戳部分，忽略时区信息
        String timestamp = dateString.replaceAll("^/Date\\((\\d+)(?:[\\+\\-]\\d+)?\\)/$", "$1");
        return timestamp;
    }

    /**
     * // 从时间戳转换为 Instant，再转换为 LocalDateTime
     *
     * @param timestamp
     * @return
     */
    public static LocalDateTime convertTimestampToLocalDateTime(long timestamp) {
        Instant instant = Instant.ofEpochMilli(timestamp);
        return LocalDateTime.ofInstant(instant, ZoneId.systemDefault());
    }

    /**
     * 定义日期时间格式
     *
     * @param dateTime
     * @return
     */
    public static String formatDateTime(LocalDateTime dateTime) {
        //
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        return dateTime.format(formatter);
    }

    public static <T> T updateFields(T obj, List<String> fields, List<String> listFields, String zibiao) {
        // 将对象转换为JSON字符串
        String jsonString = JSONUtil.toJsonStr(obj);
        JSONObject jsonObject = JSONUtil.parseObj(jsonString);

        // 遍历字段列表
        for (String field : fields) {
            // 获取指定字段的值
            String fieldValue = jsonObject.getStr(field);
            if (fieldValue != null) {
                // 提取“username”字段的值
                JSONObject fieldJson = JSONUtil.parseObj(fieldValue);
                String newValue = fieldJson.getStr("username");

                // 重新赋值给对象的同名字段
                jsonObject.set(field, newValue);
            }
        }

        // 遍历列表字段
        for (String listField : listFields) {
            // 获取列表字段的值
            JSONArray jsonArray = jsonObject.getJSONArray(zibiao);
            if (jsonArray != null) {
                for (int i = 0; i < jsonArray.size(); i++) {
                    JSONObject item = jsonArray.getJSONObject(i);
                    String d = item.getStr(listField);
                    if (d != null) {
                        JSONObject fieldJson = JSONUtil.parseObj(d);
                        // 提取并赋值“username”字段
                        String userName = fieldJson.getStr("username");
                        item.set(listField, userName); // 更新为提取的值

                    }

                }
                // 将更新后的列表重新赋值给对象
                jsonObject.set(listField, jsonArray);
            }
        }

        // 将更新后的JSON转换回对象
        return JSONUtil.toBean(jsonObject, (Class<T>) obj.getClass());
    }

    public static <T> List<T> updateFields(List<T> objList, List<String> fields) {
        List<T> updatedList = new ArrayList<>();

        for (T obj : objList) {
            // 将对象转换为JSON字符串
            String jsonString = JSONUtil.toJsonStr(obj);
            JSONObject jsonObject = JSONUtil.parseObj(jsonString);

            // 递归更新字段
            updateJsonFields(jsonObject, fields);

            // 将更新后的JSON转换回对象
            T updatedObj = JSONUtil.toBean(jsonObject, (Class<T>) obj.getClass());
            updatedList.add(updatedObj);
        }

        return updatedList;
    }

    private static void updateJsonFields(JSONObject jsonObject, List<String> fields) {
        for (String field : fields) {
            Object fieldValue = jsonObject.get(field);

            // 如果字段是字符串且是JSON格式，则解析并检查"username"字段
            if (fieldValue instanceof String && JSONUtil.isJson((String) fieldValue)) {
                JSONObject fieldJson = JSONUtil.parseObj((String) fieldValue);
                String newValue = fieldJson.getStr("username");
                if (newValue != null) {
                    jsonObject.set(field, newValue); // 更新字段
                }
            }

            // 如果字段是数组（List形式的JSONArray），递归处理其子对象
            else if (fieldValue instanceof JSONArray) {
                JSONArray jsonArray = (JSONArray) fieldValue;
                for (int i = 0; i < jsonArray.size(); i++) {
                    JSONObject item = jsonArray.getJSONObject(i);
                    updateJsonFields(item, fields); // 递归处理数组中的子对象
                }
            }

            // 如果字段是子对象（JSONObject），递归处理其字段
            else if (fieldValue instanceof JSONObject) {
                updateJsonFields((JSONObject) fieldValue, fields);
            }
        }
    }

    /**
     * 递归更新对象字段
     * @param obj
     * @return
     * @param <T>
     */
    public static <T> T updateFields(T obj) {
        // 将对象转换为JSON对象
        String jsonString = JSONUtil.toJsonStr(obj);
        JSONObject jsonObject = JSONUtil.parseObj(jsonString);

        // 递归遍历对象并更新字段
        updateJsonObject(jsonObject);

        // 将更新后的JSON对象转换回原始类型
        return JSONUtil.toBean(jsonObject, (Class<T>) obj.getClass());
    }

    // 递归更新JSON对象字段
    private static void updateJsonObject(JSONObject jsonObject) {
        for (String key : jsonObject.keySet()) {
            Object value = jsonObject.get(key);

            if (value instanceof String) {
                String strValue = (String) value;
                // 检查字符串是否是JSON格式，并且包含"username"、"dept_no"或"id"字段
                if (JSONUtil.isJson(strValue)) {
                    JSONObject fieldJson = JSONUtil.parseObj(strValue);
                    // 尝试获取 "username"
                    String newValue = fieldJson.getStr("username");
                    if (newValue == null) {
                        // 如果没有 "username"，则尝试获取 "dept_no"
                        newValue = fieldJson.getStr("dept_no");
                        if (newValue == null) {
                            // 如果没有 "dept_no"，则尝试获取 "id"
                            String idValue = fieldJson.getStr("id");
                            if (idValue != null) {
                                jsonObject.set(key, idValue); // 保留原始 "id" 值
                            }
                        } else {
                            // 如果找到了 "dept_no"，检查它是否是 Integer 类型
                            Object deptNoValue = fieldJson.get("dept_no");
                            if (deptNoValue instanceof Integer) {
                                // 如果是 Integer 类型，直接设置该值
                                jsonObject.set(key, deptNoValue);
                            } else {
                                // 如果是字符串，可以尝试转为 Integer
                                try {
                                    Integer deptNo = Integer.valueOf(fieldJson.getStr("dept_no"));
                                    jsonObject.set(key, deptNo); // 将 "dept_no" 转换为 Integer 类型
                                } catch (NumberFormatException e) {
                                    System.out.println("Invalid number format for dept_no: " + fieldJson.getStr("dept_no"));
                                }
                            }
                        }
                    } else {
                        // 如果找到了 "username" 字段，直接赋值
                        jsonObject.set(key, newValue);
                    }
                }
            } else if (value instanceof JSONObject) {
                // 递归处理嵌套的JSONObject
                updateJsonObject((JSONObject) value);
            } else if (value instanceof JSONArray) {
                // 递归处理JSONArray
                updateJsonArray((JSONArray) value);
            }
        }
    }

    // 递归更新JSONArray中的元素
    private static void updateJsonArray(JSONArray jsonArray) {
        for (int i = 0; i < jsonArray.size(); i++) {
            Object item = jsonArray.get(i);

            if (item instanceof JSONObject) {
                // 递归处理JSONArray中的JSONObject
                updateJsonObject((JSONObject) item);
            } else if (item instanceof String) {
                String strItem = (String) item;
                // 检查字符串是否是JSON格式，并且包含"username"、"name"或"id"字段
                if (JSONUtil.isJson(strItem)) {
                    JSONObject fieldJson = JSONUtil.parseObj(strItem);
                    // 尝试获取 "username"
                    String newValue = fieldJson.getStr("username");
                    if (newValue == null) {
                        // 如果没有 "username"，则尝试获取 "dept_no"
                        newValue = fieldJson.getStr("dept_no");
                        if (newValue == null) {
                            // 如果没有 "dept_no"，则尝试获取 "id"
                            String idValue = fieldJson.getStr("id");
                            if (idValue != null) {
                                jsonArray.set(i, idValue); // 保留原始 "id" 值
                            }
                        } else {
                            // 如果找到了 "dept_no"，检查它是否是 Integer 类型
                            Object deptNoValue = fieldJson.get("dept_no");
                            if (deptNoValue instanceof Integer) {
                                // 如果是 Integer 类型，直接设置该值
                                jsonArray.set(i, deptNoValue);
                            } else {
                                // 如果是字符串，可以尝试转为 Integer
                                try {
                                    Integer deptNo = Integer.valueOf(fieldJson.getStr("dept_no"));
                                    jsonArray.set(i, deptNo); // 将 "dept_no" 转换为 Integer 类型
                                } catch (NumberFormatException e) {
                                    System.out.println("Invalid number format for dept_no: " + fieldJson.getStr("dept_no"));
                                }
                            }
                        }
                    } else {
                        // 如果找到了 "username" 字段，直接赋值
                        jsonArray.set(i, newValue);
                    }
                }
            } else if (item instanceof JSONArray) {
                // 递归处理嵌套的JSONArray
                updateJsonArray((JSONArray) item);
            }
        }
    }


    /**
     * 将数字转换为以“万”为单位的格式
     * @param number
     * @return
     */
    public static String formatToWan(long number) {
        // 将数字转换为以“万”为单位的格式
        if (number >= 10000) {
            double wan = number / 10000.0; // 转换为万
            return String.format("%.1fw", wan); // 保留一位小数，添加 "w"
        }
        return String.valueOf(number); // 小于 1 万直接返回原数
    }

    /**
     * 根据销售金额返回客户等级
     *
     * @param salesAmount 销售金额
     * @return 客户等级
     */
    public static String getCustomerLevel(BigDecimal salesAmount) {
        if (salesAmount == null) {
            return "AA"; // 默认等级
        }

        if (salesAmount.compareTo(new BigDecimal("10000000")) >= 0) {
            return "GSKA";
        } else if (salesAmount.compareTo(new BigDecimal("3000000")) >= 0) {
            return "SKA";
        } else if (salesAmount.compareTo(new BigDecimal("1000000")) >= 0) {
            return "KA";
        } else if (salesAmount.compareTo(new BigDecimal("300000")) >= 0) {
            return "PA";
        } else {
            return "AA";
        }
    }

    /**
     * 先查询简道云表单数据再分批删除
     *
     * @param headers,appId,entryId
     */
    public static void selectAndDeleteList(Header[] headers,String appId, String entryId, String flag) {
        // 获取到交货单数据-简道云数据。
        List<Lin> consolidatedOrderVOList = new ArrayList<>();
        Map<String, Object> parameter = new HashMap<>();
        parameter.put("app_id", appId);
        parameter.put("entry_id", entryId);
        if(StringUtils.isNotBlank(flag)){
            Map<String, Object> filter = new HashMap<>();
            filter.put("rel", "and");
            Map<String, Object> cond = new HashMap<>();
            cond.put("field", flag);
            cond.put("type", "text");
            cond.put("method", "empty");
            List<Map<String, Object>> conds = new ArrayList<>();
            conds.add(cond);
            filter.put("cond", conds);
            parameter.put("filter", filter);
        }
        boolean fale = true;
        String zh = "";
        do {
            if (!zh.isEmpty()) {
                parameter.put("data_id", zh);
            }
            parameter.put("limit", 100);
            String jsonSale = JSONUtil.toJsonStr(parameter);
            JSONObject jdySale = ApiClient.sendPostRequest(KeyConstant.Jian_URL + "/v5/app/entry/data/list", headers, jsonSale);
            String data = jdySale.getStr("data");
            JSONArray objects = JSONUtil.parseArray(data);
            List<Lin> list = JSONUtil.toList(objects, Lin.class);
            if (list.size() == 100) {
                zh = list.getLast().get_id();
            } else {
                fale = false;
            }
            consolidatedOrderVOList.addAll(list);
        } while (fale);
        // 判断集合是否有值 有则删除 一次只能删除100条
        if (CollectionUtils.isNotEmpty(consolidatedOrderVOList)) {
            // 提取所有数据ID
            List<String> dataIds = consolidatedOrderVOList.stream()
                    .map(Lin::get_id) // get_id() 是获取数据ID的方法
                    .collect(Collectors.toList());

            int batchSize = 100;
            for (int i = 0; i < dataIds.size(); i += batchSize) {
                int endIndex = Math.min(i + batchSize, dataIds.size());
                List<String> batchDataIds = dataIds.subList(i, endIndex);

                // 构造删除接口请求参数
                Map<String, Object> deleteParam = new HashMap<>();
                deleteParam.put("app_id", appId);
                deleteParam.put("entry_id", entryId);
                deleteParam.put("data_ids", batchDataIds);

                // 发送删除请求
                String jsonDelete = JSONUtil.toJsonStr(deleteParam);
                ApiClient.sendPostRequest(KeyConstant.Jian_URL + "/v5/app/entry/data/batch_delete", headers, jsonDelete);
            }
        }
    }
    /**
     * 简道云批量新增数据
     *
     * @param headers,appId,entryId
     */
    public static void batchAddList(Header[] headers,String appId, String entryId, List<Map<String, Object>> mapList) {
        int batchSize = 100;
        for (int i = 0; i < mapList.size(); i += batchSize) {
            int endIndex = Math.min(i + batchSize, mapList.size());
            List<Map<String, Object>> batchDataIds = mapList.subList(i, endIndex);
            // 存入简道云
            Map<String, Object> parameter = new HashMap<>();
            parameter.put("app_id", appId);
            parameter.put("entry_id", entryId);
            parameter.put("data_list", batchDataIds);
            String jsonSale = JSONUtil.toJsonStr(parameter);
            ApiClient.sendPostRequest(KeyConstant.Jian_URL + "/v5/app/entry/data/batch_create", headers, jsonSale);
        }
    }

    /**
     * 提取图片文件名中 '.' 前面的名称（不含扩展名）
     * @param fileName 带扩展名的图片文件名（如 "xxx.jpg"、"abc.def.png"）
     * @return 不含扩展名的名称（如 "xxx"、"abc.def"）；若文件名无 '.' 则返回原文件名
     */
    public static String getFileNameWithoutExtension(String fileName) {
        // 判空处理
        if (fileName == null || fileName.isEmpty()) {
            return fileName;
        }

        // 找到最后一个 '.' 的位置
        int lastDotIndex = fileName.lastIndexOf('.');

        // 若没有 '.' 或 '.' 是第一个字符，则返回原文件名
        if (lastDotIndex <= 0) {
            return fileName;
        }

        // 截取 '.' 前面的部分
        return fileName.substring(0, lastDotIndex);
    }

    /**
     * 通用方法：从简道云分页获取表单数据（优化：移除System.out+批量日志）
     */
    public static <T> List<T> getJianDaoYunData(Header[] headers, String appId, String entryId, Class<T> clazz) {
        List<T> resultList = new ArrayList<>();
        Map<String, Object> params = new HashMap<>();
        params.put("app_id", appId);
        params.put("entry_id", entryId);
        boolean hasMore = true;
        String lastDataId = "";
        int pageNum = 1;

        do {
            if (!lastDataId.isEmpty()) {
                params.put("data_id", lastDataId);
            }
            params.put("limit", 100);

            String jsonParams = JSONUtil.toJsonStr(params);
            JSONObject response = ApiClient.sendPostRequest(
                    KeyConstant.Jian_URL + "/v5/app/entry/data/list",
                    headers,
                    jsonParams
            );

            String dataJson = response.getStr("data");
            JSONArray dataArray = JSONUtil.parseArray(dataJson);
            List<T> pageData = JSONUtil.toList(dataArray, clazz);

            if (pageData.size() == 100) {
                T lastData = pageData.get(pageData.size() - 1);
                lastDataId = getLastDataId(lastData);
            } else {
                hasMore = false;
            }

            resultList.addAll(pageData);
            // 替换System.out为日志，批量打印（减少IO消耗）
            if (pageNum % 10 == 0) { // 每10页打印一次
                log.info("简道云分页获取第{}页，累计数据量：{}", pageNum, resultList.size());
            }
            pageNum++;
        } while (hasMore);

        return resultList;
    }

    /**
     * 反射获取实体类的_id字段值（简道云数据默认有_id作为唯一标识）
     */
    private static <T> String getLastDataId(T data) {
        try {
            // 假设实体类有get_id()方法
            Method method = data.getClass().getMethod("get_id");
            return (String) method.invoke(data);
        } catch (Exception e) {
            // 异常处理：若没有_id字段，返回空（终止分页）
            return "";
        }
    }

}
